package net.core.service.security.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import net.core.service.security.pojos.AuthoritiesPages;

import org.apache.log4j.Logger;
/**   
 * @ClassName: SecurityFilter
 * @Description: 权限控制过滤器，过滤URL及需权限控制的页面事件ID
 * @author weixl  2010-9-14
 * @version V1.0   
 * <hr>
 * 修改记录
 * <hr>
 * 1、修改人员:    修改时间:<br>       
 *    修改内容:
 * <hr>
 */

public class SecurityFilter implements Filter{
	private Logger log = Logger.getLogger(SecurityFilter.class);
	
	//无权限访问时，转向的页面
	private String errorPage;
	//无会话时转向的页面
	private String noSessionPage;
	//用于判断会话是否为空的关键值
	private String sessionKey;// = Def.LOGIN_SESSION;
	
	private AuthoritiesPages authoritiesPages ;
	
	private Map para = new HashMap();
	
	public SecurityFilter(){
	}
	
	/**
	 * 过滤器初始化
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	/**
	 * 权限控制过滤器<br>
	 * 根据当前页面url，取得登录者权限，判断有权限的页面，才能进入，无权限页面跳转到错误页面．<br>
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
		long before = System.currentTimeMillis();
		try {
			
			String url = "";
			HttpSession session = null;
			
			if (request instanceof HttpServletRequest) {
				//取得会话 
				session = ((HttpServletRequest) request).getSession();
				
				//获取请求页面的URL地址
				url = ((HttpServletRequest) request).getServletPath();
				//不需要权限和会话判断的url url 
				boolean isNotSessionPages = false;
				if(authoritiesPages.getNotSessionPages().get(url)!=null){ 
					isNotSessionPages = true;
				} else{
					for(Iterator i = authoritiesPages.getNotSessionPages().keySet().iterator();i.hasNext();){
						String exp = (String)i.next();
						exp = exp.replaceAll("/","\\\\/");
						exp = exp.replaceAll("\\.","\\\\.");
						exp = exp.replaceAll("\\*",".*");
						//System.out.println("exp:"+exp);
						Pattern pattern = Pattern.compile(exp, Pattern.CASE_INSENSITIVE);
						Matcher matcher = pattern.matcher(url);
						if (matcher.matches()) {
							isNotSessionPages = true;
							break;
						} 
					}
				}
				if(isNotSessionPages){
					filterChain.doFilter(request,response);
					return ;
				}
			}     
			if (session == null) {
				request.getRequestDispatcher(noSessionPage).forward(request,response);
			}else if(null != sessionKey && null == session.getAttribute(sessionKey)){
				request.getRequestDispatcher(noSessionPage).forward(request,response);
			}else{ 
				filterChain.doFilter(request,response);
			}
			
			if(request.getAttribute("javax.servlet.jsp.jspException")!=null){
				Exception ex = (Exception)request.getAttribute("javax.servlet.jsp.jspException");
				if(ex.getCause()!=null){
					String msg = ex.getCause().getMessage();
					if(msg.indexOf("403")!=-1){
						throw new IOException(msg);
					}
				}
			}
			if(log.isDebugEnabled()){
				log.debug(url+":"+(before-System.currentTimeMillis()));
			}
		
		} catch (Exception e) {
			
			request.setAttribute("exception", e); 
			
			request.getRequestDispatcher(errorPage).forward(request,response);
		}
	}
	
	/**
	 * 注销方法
	 */
	public void destroy() {

	}
	
	/**
	 * 过滤器初始化
	 *
	 */
	public void doInit(){
	
	}

	/**
	 * 取得错误页面配置
	 * @return 错误页面配置
	 */
	public String getErrorPage() {
		return errorPage;
	}

	/**
	 * 设置错误页面配置 ,由spring 注入
	 * @param errorPage 错误页面配置
	 */
	public void setErrorPage(String errorPage) {
		this.errorPage = errorPage;
	}
	/**
	 * 取得不需安全过滤的页面
	 * @return 不需安全过滤的页面
	 */
	public String getNoSessionPage() {
		return noSessionPage;
	}

	/**
	 * 设置不需安全过滤的页面,由spring注入
	 * @param noSessionPage 不需安全过滤的页面
	 */
	public void setNoSessionPage(String noSessionPage) {
		this.noSessionPage = noSessionPage;
	}

	/**
	 * 取得人员信息存在会话期的key
	 * @return 人员信息存在会话期的key
	 */
	public String getSessionKey() {
		return sessionKey;
	}

	/**
	 * 设置人员信息存在会话期的key
	 * @param sessionKey　人员信息存在会话期的key
	 */
	public void setSessionKey(String sessionKey) {
		this.sessionKey = sessionKey;
	}

	public AuthoritiesPages getAuthoritiesPages() {
		return authoritiesPages;
	}

	public void setAuthoritiesPages(AuthoritiesPages authoritiesPages) {
		this.authoritiesPages = authoritiesPages;
	}

	
}